<?php

namespace app\admin\logic;

use app\admin\model\Role;
use app\admin\model\RoleNode;
use think\Exception;


/**
 * 角色
 * Class RoleLogic
 * @package app\admin\logic
 * @author ^2_3^王尔贝
 */
class RoleLogic
{
    private $roleModel;

    private $roleNodeModel;

    public function __construct()
    {
        $this->roleModel = new Role();
        $this->roleNodeModel = new RoleNode();
    }

    /**
     * 保存
     * @param array $params
     * @return bool|\think\Collection
     * @author ^2_3^王尔贝
     */
    public function save($params = [])
    {
        $flag = false;
        if( empty( $params ) ) {
            return $flag;
        }

        $this->roleModel->startTrans();
        try{
            //// role info
            $data = [];
            if( !empty( $params['id'] ) ) {
                $data['id'] = $params['id'];
            }
            $data['r_name'] = $params['r_name'] ?? '';
            $data['remark'] = $params['remark'] ?? '';
            $data['status'] = $params['status'] ?? '';
            $rFlag = $this->roleModel->_saveAll( [$data] );
            $roleId = 0;
            if( $rFlag === false ) {
                $this->roleModel->rollback();
                $flag = false;
                return $flag;
            }else {
                $roleId = $rFlag[0]['id'];
            }

            //// role node
            $rnWhere = [
                'role_id' => $roleId,
            ];
            $nodeIds = $this->roleNodeModel->_column($rnWhere, 'node_id');

            $rnaFlag = true;
            $rndFlag = true;
            $rnAdd = [];
            $rnDel = [];
            if( empty( $params['nodes'] ) && empty( $nodeIds ) ) {

            }else if( !empty( $params['nodes'] ) && empty( $nodeIds ) ) {
                $rnAdd = $params['nodes'];

            }else if( empty( $params['nodes'] ) && !empty( $nodeIds ) ) {
                $rnDel = $nodeIds;

            }else {
                $rnAdd = array_diff($params['nodes'], $nodeIds);
                $rnDel = array_diff($nodeIds, $params['nodes']);
            }

            if( !empty( $rnAdd ) ) {
                $rnAddData = [];
                foreach ($rnAdd as $nId) {
                    $rnAddData[] = [
                        'role_id' => $roleId,
                        'node_id' => $nId,
                        'created_at' => time(),
                    ];
                }
                $rnaFlag = $this->roleNodeModel->_saveAll( $rnAddData );
            }

            if ($rnaFlag !== false && !empty( $rnDel )) {
                $delWhere = [
                    ['role_id', '=', $roleId],
                    ['node_id', 'in', $rnDel],
                ];
                $rndFlag = $this->roleNodeModel->_delete($delWhere);
            }

            if( $rFlag !== false && $rnaFlag !== false && $rndFlag !== false ) {
                $this->roleModel->commit();
                $flag = true;

            }else {
                $this->roleModel->rollback();
                $flag = false;
            }

        }catch (Exception $e) {
            $this->roleModel->rollback();
            $flag = false;
        }

        return $flag;
    }

    /**
     * node节点
     * @param array $params
     * @return array
     * @author ^2_3^王尔贝
     */
    public function roleNodes($params = [])
    {
        $roleNodes = [];
        if( empty( $params['role_id'] ) ) {
            return $roleNodes;
        }

        $where = [
            'role_id' => $params['role_id'],
        ];
        $roleNodes = $this->roleNodeModel->_column($where, 'node_id');

        return $roleNodes;
    }

    /**
     * 有效角色
     * @param array $params
     * @return \think\response\Json
     * @author ^2_3^王尔贝
     */
    public function validRoles($params = [])
    {
        $where = [
            'status' => 1,
        ];
        $field = 'id, id as `key`, r_name';
        $list = $this->roleModel->listOnly($where, $field, 'id asc');
        return $list;
    }

    /**
     * 分页列表
     * @param array $params
     * @return mixed
     * @author ^2_3^王尔贝
     */
    public function listPage($params = [])
    {
        $where = [];
        if( !empty( $params['id'] ) ) {
            $where['id'] = $params['id'];
        }
        if( !empty( $params['r_name'] ) ) {
            $where[] = ['r_name', 'like', "%{$params['r_name']}%"];
        }
        if( !empty( $params['status'] ) && $params['status'] == 1 ) {
            $where['status'] = 1; // 正常；

        }else if( !empty( $params['status'] ) && $params['status'] == 2 ) {
            $where['status'] = 0; // 禁用；
        }
        $orderBy = '';
        if( !empty( $params['sortField'] ) ) {
            $sortField = $params['sortField'];
            $sortOrder = $params['sortOrder'] ?? 'desc';
            $orderBy = "{$sortField} {$sortOrder}";

        }else {
            $orderBy = "id desc";
        }

        $field = 'id, id as `key`, r_name, remark, status, created_at, updated_at';
        $page = $params['pageNo'] ?? 1;
        $pageSize = $params['pageSize'] ?? 10;
        $listPage = $this->roleModel->listPage($where, $field, $page, $orderBy, $pageSize);

        //// role node
        if( !$listPage->isEmpty() ) {
            $roleIds = array_column((array)$listPage->items(), 'id');
            $rnWhere = [
                ['role_id', 'in', implode(',', $roleIds)],
            ];
            $rnList = $this->roleNodeModel->listOnly($rnWhere, 'role_id, node_id');
            $rnArr = [];
            foreach ($rnList as $roleNode) {
                $rnArr[ $roleNode['role_id'] ][] = ['value' => $roleNode['node_id']];
            }

            foreach ($listPage->items() as $item) {
                if( isset( $rnArr[ $item['id'] ] ) ) {
                    $item['nodes'] = $rnArr[ $item['id'] ];
                }
            }
        }

        return $listPage;
    }
}